#include "rstatagent.h"
#include "rstat_clnt/rsysinfo.h"
#include <QDebug>

RstatAgent::RstatAgent(std::string ip):
	m_ip(ip),
	m_timer(NULL)
{
	memset(&m_rstatData, 0, sizeof(TRstatData));
	m_pageout_scale = m_pagein_scale = 1;
	m_packetout_scale = m_packetin_scale = 1;
	m_intr_scale = 1;
	m_context_sw_scale = 1;
}

std::string RstatAgent::getServerIP()
{
	return m_ip;
}

void RstatAgent::setServerIP(std::string ip)
{
	// should do some check here
	m_ip = ip;
}

// slots

void RstatAgent::getRstat()
{
	static struct statstime old_stat;
	static int flag = 0;
	struct statstime host_stat;

	if(get_rstat(m_ip.c_str(), &host_stat)){
		// if no old data available
		if(flag == 0){
			flag = 1;
			old_stat = host_stat;
			return;
		}
	// cpu utilization
		double total = (double)host_stat.cp_time[0]
			+ host_stat.cp_time[1]
			+ host_stat.cp_time[2]
			+ host_stat.cp_time[3]
			- old_stat.cp_time[0]
			- old_stat.cp_time[1]
			- old_stat.cp_time[2]
			- old_stat.cp_time[3];
		
		m_rstatData.cpu_ratio = (host_stat.cp_time[3] - old_stat.cp_time[3]) / total;
		m_rstatData.cpu_ratio = 1.0 - m_rstatData.cpu_ratio;
		m_rstatData.cpu_ratio *= 100;
		
	// page in
		double page_in = host_stat.v_pgpgin - old_stat.v_pgpgin;
		// adjust scale
		while(page_in / m_pagein_scale > 100){
			m_pagein_scale *= 10;
		}
	// page out
		double page_out = host_stat.v_pgpgout - old_stat.v_pgpgout;
		// adjust scale
		while(page_out / m_pageout_scale > 100){
			m_pageout_scale *= 10;
		}
	// intr
		double intr = host_stat.v_intr - old_stat.v_intr;
		while(intr / m_intr_scale > 100){
			m_intr_scale *= 10;
		}
	// context switch
		double context_sw = host_stat.v_swtch - old_stat.v_swtch;
		while(context_sw / m_context_sw_scale > 100){
			m_context_sw_scale *= 10;
		}
	// packet in
		double packet_in = host_stat.if_ipackets - old_stat.if_ipackets;
		while(packet_in / m_packetin_scale > 100){
			m_packetin_scale *= 10;
		}
	// packet out
		double packet_out = host_stat.if_opackets - old_stat.if_opackets;
		while(packet_out / m_packetout_scale > 100){
			m_packetout_scale *= 10;
		}

		m_rstatData.page_in = page_in / m_pagein_scale;
		m_rstatData.page_out = page_out / m_pageout_scale;
		m_rstatData.intr = intr / m_intr_scale;
		m_rstatData.context_sw = context_sw / m_context_sw_scale;
		m_rstatData.packet_in = packet_in / m_packetin_scale;
		m_rstatData.packet_out = packet_out / m_packetout_scale;

		/*
		qDebug() << "cpu: " << m_rstatData.cpu_ratio;
		qDebug() << "page in: " << m_rstatData.page_in << ", scale: " << m_pagein_scale;
		qDebug() << "page out: " << m_rstatData.page_out << ", scale: " << m_pageout_scale;
		qDebug() << "intr: " << m_rstatData.intr << ", scale: " << m_intr_scale;
		qDebug() << "context: " << m_rstatData.context_sw << ", scale: " << m_context_sw_scale;
		qDebug() << "packet in: " << m_rstatData.packet_in << ", scale: " << m_packetin_scale;
		qDebug() << "packet out: " << m_rstatData.packet_out << ", scale: " << m_packetout_scale;
		*/

		old_stat = host_stat;
	} else {
		qDebug() << "RstatAgent::get_rstat() failed";
		return;
	}

	emit rstatDataArrived(m_rstatData);
}

// run when thread start
void RstatAgent::InitAgent()
{
	if(m_timer == NULL){
		m_timer = new QTimer(this);
		QObject::connect(m_timer, SIGNAL(timeout()), this, SLOT(getRstat()));
		m_timer->start(5000);
		// to fill old_stat, shorten response time
		this->getRstat();
	}
	//qDebug() << "rstat agent started";
}

void RstatAgent::SetServerIP(std::string ip)
{
	this->setServerIP(ip);
}
